package com.dianxin.smartpark.service.park.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import com.chinatelecom.response.common.CommonResponseBody;
import com.chinatelecom.response.utils.BeanUtil;
import com.chinatelecom.response.utils.Convert;
import com.chinatelecom.response.utils.ResponseBodyWrapperUtil;
import com.chinatelecom.response.constant.ErrMsgEnum;

import com.chinatelecom.response.utils.StringUtils;
import com.dianxin.device.api.device.SmartDeviceUserRpcService;
import com.dianxin.device.api.device.SmartParkDeviceRpcService;
import com.dianxin.device.api.device.dto.SmartDeviceDTO;
import com.dianxin.device.api.device.dto.SmartDeviceUserDTO;
import com.dianxin.device.api.device.qo.SmartDeviceRpcQO;
import com.dianxin.device.api.device.qo.SmartDeviceUserRpcQO;
import com.dianxin.smartpark.dao.dataobject.common.SmartParkCard;
import com.dianxin.smartpark.dao.dataobject.common.SmartParkCardExample;
import com.dianxin.smartpark.dao.dataobject.common.SmartParkUserConfig;
import com.dianxin.smartpark.dao.dataobject.common.SmartParkUserConfigExample;
import com.dianxin.smartpark.dao.dataobject.park.SmartParkCar;
import com.dianxin.smartpark.dao.dataobject.park.SmartParkCarExample;
import com.dianxin.smartpark.dao.dataobject.visitor.SmartParkStrategyConfig;
import com.dianxin.smartpark.dao.dataobject.visitor.SmartParkStrategyConfigExample;
import com.dianxin.smartpark.dao.dataobject.visitor.SmartParkVisitor;
import com.dianxin.smartpark.dao.dataobject.visitor.SmartParkVisitorExample;
import com.dianxin.smartpark.dao.mapper.common.SmartParkUserConfigMapper;
import com.dianxin.smartpark.dao.mapper.park.SmartParkCarMapper;
import com.dianxin.smartpark.dao.mapper.visitor.SmartParkStrategyConfigMapper;
import com.dianxin.smartpark.dao.mapper.visitor.SmartParkVisitorMapper;
import com.dianxin.smartpark.dao.qo.park.SmartParkCarQO;
import com.dianxin.smartpark.service.common.SmartParkDeviceAuthService;
import com.dianxin.smartpark.service.common.SmartParkUserConfigService;
import com.dianxin.smartpark.service.config.MqttOptType;
import com.dianxin.smartpark.service.park.SmartParkCarService;
import com.dianxin.smartpark.service.vo.common.SmartParkUserCardVO;
import com.dianxin.smartpark.service.vo.park.DevicePullDataCarVo;
import com.dianxin.smartpark.service.vo.park.SmartParkCarVO;
import com.dianxin.smartpark.service.vo.park.SmartParkUserCarVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * 车辆管理业务层处理
 * 
 * @author chenjiasong
 * @date 2021-07-28
 */
@Service
public class SmartParkCarServiceImpl implements SmartParkCarService
{
    private final static Logger logger = LoggerFactory.getLogger(SmartParkCarServiceImpl.class);
    @Resource
    private SmartParkCarMapper smartParkCarMapper;

    @Resource
    private SmartParkDeviceAuthService smartParkDeviceAuthService;

    @Resource
    private SmartParkUserConfigMapper smartParkUserConfigMapper;

    @Resource
    private SmartParkVisitorMapper smartParkVisitorMapper;

    @Resource
    private SmartParkStrategyConfigMapper smartParkStrategyConfigMapper;

    @Resource
    private SmartParkDeviceRpcService smartParkDeviceRpcService;

    /**
     * 查询车辆管理
     * 
     * @param qo 车辆管理ID
     * @return 车辆管理
     */
    @Override
    public CommonResponseBody<SmartParkCarVO> selectSmartParkCar(SmartParkCarQO qo)
    {
        if(StringUtils.isNull(qo.getId())){
            return ResponseBodyWrapperUtil.fail(ErrMsgEnum.ERROR_PARAME);
        }
        SmartParkCarExample smartParkCarExample = new SmartParkCarExample();
        SmartParkCarExample.Criteria criteria = smartParkCarExample.createCriteria();
        if (qo.getTenantId() != null) {
            criteria.andTenantIdEqualTo(qo.getTenantId());
        }
        criteria.andIsDeletedEqualTo(0);
        criteria.andIdEqualTo(qo.getId());
        List<SmartParkCar> passRecords = smartParkCarMapper.selectByExample(smartParkCarExample);
        return ResponseBodyWrapperUtil.successWrapper(StringUtils.isNotEmpty(passRecords)?passRecords.get(0):null,SmartParkCarVO.class);
    }

    @Override
    public CommonResponseBody<List<SmartParkUserCarVO>> selectSmartParkUserCarList(DevicePullDataCarVo vo) throws Exception {
        List<SmartParkUserCarVO> result = new ArrayList<>();
        //查询拥有设备权限所有人
        List<String>userIds = smartParkDeviceAuthService.getUserIdByDeviceCode(vo.getDeviceCode(),vo.getOrgCode(),vo.getTenantId());
        SmartParkCarExample smartParkCarExample = new SmartParkCarExample();
        SmartParkCarExample.Criteria carExampleCriteria = smartParkCarExample.createCriteria();
        if (vo.getTenantId() != null) {
            carExampleCriteria.andTenantIdEqualTo(vo.getTenantId());
        }
        carExampleCriteria.andIsDeletedEqualTo(0);
        List<SmartParkCar> carList = smartParkCarMapper.selectByExample(smartParkCarExample);

        //查询设备区域
        SmartDeviceRpcQO smartDeviceRpcQO = new SmartDeviceRpcQO();
        smartDeviceRpcQO.setTenantId(vo.getTenantId());
        smartDeviceRpcQO.setOrgCode(Convert.toStr(vo.getOrgCode()));
        smartDeviceRpcQO.setDeviceCode(vo.getDeviceCode());
        smartDeviceRpcQO.setNeedPage(false);
        CommonResponseBody<List<SmartDeviceDTO>> smartParkDeviceRpcServiceDevices = smartParkDeviceRpcService.getDevices(smartDeviceRpcQO);
        if(!smartParkDeviceRpcServiceDevices.isSuccess() || StringUtils.isEmpty(smartParkDeviceRpcServiceDevices.getData())){
            return ResponseBodyWrapperUtil.successWrapper(result);
        }
        SmartDeviceDTO smartDeviceDTO = smartParkDeviceRpcServiceDevices.getData().get(0);

        //访客设备权限判断
        boolean visitorFlag = false;
        //查访客配置
        SmartParkStrategyConfigExample smartParkStrategyConfigExample = new SmartParkStrategyConfigExample();
        SmartParkStrategyConfigExample.Criteria configExampleCriteria = smartParkStrategyConfigExample.createCriteria();
        configExampleCriteria.andTenantIdEqualTo(smartDeviceDTO.getTenantId());
        List<SmartParkStrategyConfig> strategyConfigs = smartParkStrategyConfigMapper.selectByExample(smartParkStrategyConfigExample);
        if(StringUtils.isNotNull(strategyConfigs)){
            //判断权限区域
            SmartParkStrategyConfig strategyConfig = strategyConfigs.get(0);
            if(StringUtils.isNotEmpty(strategyConfig.getDeviceCodes())){
                visitorFlag = strategyConfig.getDeviceCodes().contains(smartDeviceDTO.getDeviceAreaCode());
            }
        }
        //查询员工凭证
        SmartParkUserConfigExample smartParkUserConfigExample = new SmartParkUserConfigExample();
        SmartParkUserConfigExample.Criteria configExampleCriteria1 = smartParkUserConfigExample.createCriteria();
        configExampleCriteria1.andIsDeletedEqualTo(0);
        configExampleCriteria1.andAccessStartDateLessThanOrEqualTo(new Date());
        configExampleCriteria1.andAccessEndDateGreaterThanOrEqualTo(new Date());
        configExampleCriteria1.andBeAccessCarEqualTo(1);
        List<SmartParkUserConfig> smartParkUserConfigs = smartParkUserConfigMapper.selectByExample(smartParkUserConfigExample);
        List<SmartParkVisitor> smartParkVisitors = null;
        if(visitorFlag){
            //查询访客
            SmartParkVisitorExample smartParkVisitorExample = new SmartParkVisitorExample();
            SmartParkVisitorExample.Criteria parkVisitorExampleCriteria = smartParkVisitorExample.createCriteria();
            parkVisitorExampleCriteria.andIsDeletedEqualTo(0);
            parkVisitorExampleCriteria.andAccessStartDateLessThanOrEqualTo(new Date());
            parkVisitorExampleCriteria.andAccessEndDateGreaterThanOrEqualTo(new Date());
            parkVisitorExampleCriteria.andBeAccessCarEqualTo(1);
            smartParkVisitors = smartParkVisitorMapper.selectByExample(smartParkVisitorExample);
        }
        for (SmartParkCar car:carList) {
            //员工
            if(car.getUserType()==1){
                if(!userIds.contains(Convert.toStr(car.getUserId()))){
                    continue;
                }
                if(StringUtils.isEmpty(smartParkUserConfigs)){
                    break;
                }
                List<SmartParkUserConfig> smartParkUserConfigList = smartParkUserConfigs.stream().filter(u->u.getUserId().equals(Convert.toStr(car.getUserId()))).collect(Collectors.toList());
                if (StringUtils.isEmpty(smartParkUserConfigList)) {
                    continue;
                }
                SmartParkUserConfig smartParkUserConfig = smartParkUserConfigList.get(0);
                if(smartParkUserConfig.getBeAccessCar()==0){
                    continue;
                }
                SmartParkUserCarVO smartParkUserCarVO = new SmartParkUserCarVO();
                smartParkUserCarVO.setUserId(Convert.toLong(smartParkUserConfig.getUserId()));
                smartParkUserCarVO.setUserType(1);
                smartParkUserCarVO.setPhoneNum(smartParkUserConfig.getPhoneNum());
                smartParkUserCarVO.setUserName(smartParkUserConfig.getName());
                if(smartParkUserConfig.getAccessDateType()==1) {
                    smartParkUserCarVO.setAccessStartDate(smartParkUserConfig.getAccessStartDate().getTime());
                    smartParkUserCarVO.setAccessEndDate(smartParkUserConfig.getAccessEndDate().getTime());
                }
                smartParkUserCarVO.setGmtModified(smartParkUserConfig.getGmtModified()==null?smartParkUserConfig.getGmtCreate().getTime():smartParkUserConfig.getGmtModified().getTime());
                smartParkUserCarVO.setCarNum(car.getLicensePlate());
                result.add(smartParkUserCarVO);
                //访客
            }else if(visitorFlag && car.getUserType()==2){
                if(StringUtils.isEmpty(smartParkVisitors)){
                    break;
                }
                SmartParkVisitor smartParkVisitor = null;
                for(SmartParkVisitor smartParkVisitor1 :smartParkVisitors){
                    if(smartParkVisitor1.getId().equals(Convert.toStr(car.getUserId()))){
                        smartParkVisitor = smartParkVisitor1;
                        break;
                    }
                }
                if (StringUtils.isNull(smartParkVisitor)) {
                    continue;
                }

                if(smartParkVisitor.getBeAccessCar()==0){
                    continue;
                }
                //装载数据
                SmartParkUserCarVO smartParkUserCarVO = new SmartParkUserCarVO();
                smartParkUserCarVO.setUserId(smartParkVisitor.getId());
                smartParkUserCarVO.setUserType(2);
                smartParkUserCarVO.setPhoneNum(smartParkVisitor.getVisitorPhoneNum());
                smartParkUserCarVO.setUserName(smartParkVisitor.getVisitorName());
                if(smartParkVisitor.getAccessDateType()==1) {
                    smartParkUserCarVO.setAccessStartDate(smartParkVisitor.getAccessStartDate().getTime());
                    smartParkUserCarVO.setAccessEndDate(smartParkVisitor.getAccessEndDate().getTime());
                }
                smartParkUserCarVO.setGmtModified(smartParkVisitor.getGmtModified()==null?smartParkVisitor.getGmtCreate().getTime():smartParkVisitor.getGmtModified().getTime());
                smartParkUserCarVO.setCarNum(car.getLicensePlate());
                result.add(smartParkUserCarVO);
            }
        }
        //查询员工，装载数据
        return ResponseBodyWrapperUtil.successWrapper(result);
    }

    @Override
    public CommonResponseBody<SmartParkUserCarVO> selectSmartParkUserCarListByCar(DevicePullDataCarVo vo) throws Exception {
        //查询卡号
        SmartParkCarExample smartParkCarExample = new SmartParkCarExample();
        SmartParkCarExample.Criteria carExampleCriteria = smartParkCarExample.createCriteria();
        carExampleCriteria.andIsDeletedEqualTo(0);
        smartParkCarExample.setOrderByClause("gmt_create desc");
        carExampleCriteria.andLicensePlateEqualTo(vo.getCarNum());
        List<SmartParkCar> smartParkCars = smartParkCarMapper.selectByExample(smartParkCarExample);
        if(StringUtils.isEmpty(smartParkCars)){
            return ResponseBodyWrapperUtil.fail("无效车牌","400");
        }
        SmartParkCar smartParkCar = smartParkCars.get(0);
        SmartParkUserCarVO smartParkUserCarVO = new SmartParkUserCarVO();
        smartParkUserCarVO.setCarNum(vo.getCarNum());
        //员工
        if(smartParkCar.getUserType()==1){
            //如果没有设备权限
            if(!smartParkDeviceAuthService.authUserIdandDeviceCode(vo.getDeviceCode(),Convert.toStr(smartParkCar.getUserId()),vo.getOrgCode(),vo.getTenantId())){
                return ResponseBodyWrapperUtil.fail("无效车牌","400");
            }
            //查询员工凭证
            SmartParkUserConfigExample smartParkUserConfigExample = new SmartParkUserConfigExample();
            SmartParkUserConfigExample.Criteria criteria = smartParkUserConfigExample.createCriteria();
            criteria.andIsDeletedEqualTo(0);
            criteria.andAccessStartDateLessThanOrEqualTo(new Date());
            criteria.andAccessEndDateGreaterThanOrEqualTo(new Date());
            criteria.andUserIdEqualTo(Convert.toLong(smartParkCar.getUserId()));
            List<SmartParkUserConfig> passRecords = smartParkUserConfigMapper.selectByExample(smartParkUserConfigExample);
            if(StringUtils.isEmpty(passRecords)){
                return ResponseBodyWrapperUtil.fail("无效车牌","400");
            }
            SmartParkUserConfig smartParkUserConfig = passRecords.get(0);
            if(smartParkUserConfig.getBeAccessCar()==0){
                return ResponseBodyWrapperUtil.fail("无效车牌","400");
            }
            smartParkUserCarVO.setUserId(Convert.toLong(smartParkUserConfig.getUserId()));
            smartParkUserCarVO.setUserType(1);
            smartParkUserCarVO.setPhoneNum(smartParkUserConfig.getPhoneNum());
            smartParkUserCarVO.setUserName(smartParkUserConfig.getName());
            if(smartParkUserConfig.getAccessDateType()==1) {
                smartParkUserCarVO.setAccessStartDate(smartParkUserConfig.getAccessStartDate().getTime());
                smartParkUserCarVO.setAccessEndDate(smartParkUserConfig.getAccessEndDate().getTime());
            }
            smartParkUserCarVO.setGmtModified(smartParkUserConfig.getGmtModified()==null?smartParkUserConfig.getGmtCreate().getTime():smartParkUserConfig.getGmtModified().getTime());
            //访客
        }else if(smartParkCar.getUserType()==2){
            SmartParkVisitorExample smartParkVisitorExample = new SmartParkVisitorExample();
            SmartParkVisitorExample.Criteria criteria = smartParkVisitorExample.createCriteria();
            criteria.andIsDeletedEqualTo(0);
            criteria.andIdEqualTo(Convert.toLong(smartParkCar.getUserId()));
            criteria.andAccessStartDateLessThanOrEqualTo(new Date());
            criteria.andAccessEndDateGreaterThanOrEqualTo(new Date());
            List<SmartParkVisitor> passRecords = smartParkVisitorMapper.selectByExample(smartParkVisitorExample);
            if(StringUtils.isEmpty(passRecords)){
                return ResponseBodyWrapperUtil.fail("无效车牌","400");
            }
            SmartParkVisitor smartParkVisitor = passRecords.get(0);
            if(smartParkVisitor.getBeAccessCar()==0){
                return ResponseBodyWrapperUtil.fail("无效车牌","400");
            }
            smartParkUserCarVO.setUserId(smartParkVisitor.getId());
            smartParkUserCarVO.setUserType(2);
            smartParkUserCarVO.setPhoneNum(smartParkVisitor.getVisitorPhoneNum());
            smartParkUserCarVO.setUserName(smartParkVisitor.getVisitorName());
            if(smartParkVisitor.getAccessDateType()==1) {
                smartParkUserCarVO.setAccessStartDate(smartParkVisitor.getAccessStartDate().getTime());
                smartParkUserCarVO.setAccessEndDate(smartParkVisitor.getAccessEndDate().getTime());
            }
            smartParkUserCarVO.setGmtModified(smartParkVisitor.getGmtModified()==null?smartParkVisitor.getGmtCreate().getTime():smartParkVisitor.getGmtModified().getTime());
        }
        return ResponseBodyWrapperUtil.successWrapper(smartParkUserCarVO);
    }

    /**
     * 查询车辆管理列表
     * 
     * @param qo 车辆管理
     * @return 车辆管理
     */
    @Override
    public CommonResponseBody<List<SmartParkCarVO>> selectSmartParkCarList(SmartParkCarQO qo)
    {
        SmartParkCarExample smartParkCarExample = new SmartParkCarExample();
        SmartParkCarExample.Criteria criteria = smartParkCarExample.createCriteria();
        if (qo.getTenantId() != null) {
            criteria.andTenantIdEqualTo(qo.getTenantId());
        }
        criteria.andIsDeletedEqualTo(0);
        if (qo.getNeedPage()) {
            smartParkCarExample.setOrderByClause("gmt_create desc limit " + (qo.getPageIndex() - 1) * qo.getPageSize() + "," + qo.getPageSize());
        } else {
            smartParkCarExample.setOrderByClause("gmt_create desc");
        }
        if (qo.getCarType() != null) {
            criteria.andCarTypeEqualTo(qo.getCarType());
        }
        if (qo.getUserId() != null) {
            criteria.andUserIdEqualTo(qo.getUserId());
        }
        if (qo.getLicensePlate() != null) {
            criteria.andLicensePlateLike("%"+qo.getLicensePlate()+"%");
        }
        if (qo.getUserName() != null) {
            criteria.andUserNameLike("%"+qo.getUserName()+"%");
        }
        List<SmartParkCar> passRecords = smartParkCarMapper.selectByExample(smartParkCarExample);
        long count = smartParkCarMapper.countByExample(smartParkCarExample);
        return ResponseBodyWrapperUtil
                .successListWrapper(passRecords, count, qo, SmartParkCarVO.class);
    }

    /**
     * 新增车辆管理
     * 
     * @param vo 车辆管理
     * @return 结果
     */
    @Override
    public CommonResponseBody<Boolean> insertSmartParkCar(SmartParkCarVO vo) throws Exception {
        if (StringUtils.isEmpty(vo.getLicensePlate())) {
            return ResponseBodyWrapperUtil.fail("车牌号为空","400");
        }
        if (StringUtils.isNull(vo.getUserId())) {
            return ResponseBodyWrapperUtil.fail("用户id为空","400");
        }
        // 验证 todo
        SmartParkCar smartParkCar = new SmartParkCar();
        try {
            BeanUtil.insertConversion(vo, smartParkCar);
        } catch (Exception e) {
            logger.error("", e);
        }
        smartParkCar.beforeInsert();
        smartParkCar.setLicensePlate(vo.getLicensePlate().toUpperCase());
        SmartParkCarExample smartParkCarExample = new SmartParkCarExample();
        SmartParkCarExample.Criteria criteria = smartParkCarExample.createCriteria();
        if (vo.getTenantId() != null) {
            criteria.andTenantIdEqualTo(vo.getTenantId());
        }
        criteria.andIsDeletedEqualTo(0);
        criteria.andLicensePlateEqualTo(smartParkCar.getLicensePlate());
        List<SmartParkCar> passRecords = smartParkCarMapper.selectByExample(smartParkCarExample);
        if(StringUtils.isNotEmpty(passRecords)){
            return ResponseBodyWrapperUtil.fail("车牌已绑定","400");
        }
        int res = smartParkCarMapper.insertSelective(smartParkCar);
        //新增车牌
        if(res>0 && StringUtils.isNotNull(vo.getUserId())){
            smartParkDeviceAuthService.sendUserDeviceAuth(Convert.toStr(vo.getUserId()),MqttOptType.ADDUSERCAR.getOptCode(),smartParkCar.getLicensePlate());
        }
        return ResponseBodyWrapperUtil.toResData(res);
    }

    /**
     * 修改车辆管理
     * 
     * @param vo 车辆管理
     * @return 结果
     */
    @Override
    public CommonResponseBody<Boolean> updateSmartParkCar(SmartParkCarVO vo)
    {
        // 验证 todo
        SmartParkCar smartParkCar = new SmartParkCar();
        try {
            BeanUtil.insertConversion(vo, smartParkCar);
        } catch (Exception e) {
            logger.error("", e);
        }
        smartParkCar.beforeUpdate();
        return ResponseBodyWrapperUtil.toResData(smartParkCarMapper.updateByPrimaryKeySelective(smartParkCar));
    }

    /**
     * 删除车辆管理信息
     * 
     * @param vo 车辆管理
     * @return 结果08
     */
    @Override
    public CommonResponseBody<Boolean> deleteSmartParkCar(SmartParkCarVO vo) throws Exception {
        // 验证 todo
        if(StringUtils.isNull(vo.getId())){
            return ResponseBodyWrapperUtil.fail(ErrMsgEnum.ERROR_PARAME);
        }
        SmartParkCar smartParkCar = new SmartParkCar();
        try {
            BeanUtil.insertConversion(vo, smartParkCar);
        } catch (Exception e) {
            logger.error("", e);
        }
        smartParkCar.beforeDelete();
        int res = smartParkCarMapper.updateByPrimaryKeySelective(smartParkCar);
        smartParkCar = smartParkCarMapper.selectByPrimaryKey(vo.getId());
        //删除车牌
        if(res>0 && StringUtils.isNotNull(vo.getUserId())){
            smartParkDeviceAuthService.sendUserDeviceDelAuth(Convert.toStr(vo.getUserId()),MqttOptType.DELUSERCAR.getOptCode(),smartParkCar.getLicensePlate());
        }
        return ResponseBodyWrapperUtil.toResData(res);
    }
}
